package com.lg.partition16;

import java.io.*;

/**
 * @author `RKC`
 * @date 2022/4/13 10:09
 */
public class P1522牛的旅行CowTours {

    private static final int N = 155, INF = 0x3f3f3f3f;
    private static int[][] pairs = new int[N][2];
    private static double[][] dist = new double[N][N];
    //maxd[i]表示在当前连通块内，i节点能走到的最远距离
    private static double[] maxd = new double[N];
    private static int n;

    private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        n = Integer.parseInt(reader.readLine());
        for (int i = 1; i <= n; i++) {
            String[] ss = reader.readLine().split(" ");
            int a = Integer.parseInt(ss[0]), b = Integer.parseInt(ss[1]);
            pairs[i] = new int[]{a, b};
        }
        for (int i = 1; i <= n; i++) {
            String s = reader.readLine();
            for (int j = 1; j <= n; j++) {
                if (i == j) continue;
                if (s.charAt(j - 1) == '0') dist[i][j] = INF;
                else {
                    int[] p1 = pairs[i], p2 = pairs[j];
                    dist[i][j] = dist[j][i] = get(p1[0], p1[1], p2[0], p2[1]);
                }
            }
        }
        writer.write(String.format("%.6f\n", resolve()));
        writer.flush();
    }

    private static double resolve() {
        //floyd预处理出来连通块内任意两个节点的最短距离
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
        //找出当前节点在当前连通块的最远距离
        double ans1 = 0, ans2 = INF;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (dist[i][j] >= INF) continue;
                maxd[i] = Math.max(maxd[i], dist[i][j]);
                ans1 = Math.max(ans1, maxd[i]);
            }
        }
        //找出两个不同连通块的最短距离
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (dist[i][j] < INF) continue;
                double d = get(pairs[i][0], pairs[i][1], pairs[j][0], pairs[j][1]);
                ans2 = Math.min(ans2, maxd[i] + maxd[j] + d);
            }
        }
        return Math.max(ans1, ans2);
    }

    private static double get(int x1, int y1, int x2, int y2) {
        int x = Math.abs(x1 - x2), y = Math.abs(y1 - y2);
        return Math.sqrt(x * x + y * y);
    }
}
